import axios, { AxiosInstance } from 'axios';
import { ElMessage } from 'element-plus';
import { Session, Local } from '/@/utils/storage';
import { router } from '/@/router/index';

// 配置新建一个 axios 实例
const service: AxiosInstance = axios.create({
	baseURL: import.meta.env.VITE_API_URL,
	timeout: 50000,
	headers: { 'Content-Type': 'application/json' },
});

// 添加请求拦截器
service.interceptors.request.use(
	(config: { headers: any; }) => {
		var curTime = new Date()
		var tokenExpire = Local.get('tokenExpire') || ''
		// 在发送请求之前做些什么 token
		if (tokenExpire && curTime < new Date(Date.parse(tokenExpire)) && Session.get('token')) {
			config.headers!['Authorization'] = `Bearer ${Session.get('token')}`;
		}

		saveRefreshtime();
		return config;
	},
	(error: any) => {
		// 对请求错误做些什么
		return Promise.reject(error);
	}
);

export const saveRefreshtime = () => {

    let nowtime = new Date();
    let lastRefreshtime = Local.get('refreshTime') ? new Date(Local.get('refreshTime')) : new Date(-1);
    let expiretime = new Date(Date.parse(Local.get('tokenExpire')))

    let refreshCount=1;//滑动系数
    if (lastRefreshtime >= nowtime) {
        lastRefreshtime=nowtime>expiretime ? nowtime:expiretime;
        lastRefreshtime.setMinutes(lastRefreshtime.getMinutes() + refreshCount);
        Local.set('refreshTime', lastRefreshtime);
    }else {
		Local.set('refreshTime', new Date(-1))
    }
};

// 添加响应拦截器
service.interceptors.response.use(
	(res: any) => {
		// 返回api真正的json结构数据，调用方直接可用
        //{"data":null,"msg":"","msgDev":null,"status":500,"success":false}
		return res.data;
	},
	(error: any) => {
        console.log(error)
		// 对响应错误做点什么
		let errInfo = { success: false, message: "错误" }
        // 超时请求处理
        var originalRequest = error.config;
        if(error.code == 'ECONNABORTED' && error.message.indexOf('timeout')!=-1 && !originalRequest._retry){
            errInfo.message = "请求超时！"; 
            originalRequest._retry = true 
        }else if (error.response) {
            let response = error.response;
            if (response.status == 401) {
                var curTime = new Date()
                var refreshTime = new Date(Date.parse(Local.get('refreshTime')))
                // 在用户操作的活跃期内
                if (Local.get('refreshTime') && (curTime <= refreshTime) && !originalRequest._retry) {
                    return refreshToken({token: Session.get('token')}).then((res: any) => {
                        if (res.success) {
                            Session.set('token', res.data.token)

                            var curTime = new Date();
                            var expiredate = new Date(curTime.setSeconds(curTime.getSeconds() + res.data.expires_in));
                            Local.set("tokenExpire", expiredate);

                            originalRequest._retry = true;
                            originalRequest.headers.Authorization = 'Bearer ' + res.data.token;
                            return axios(originalRequest);
                        } else {
                            // 刷新token失败 清除token信息并跳转到登录页面
                            ToLogin()
                        }
                    });
                } else {
                    // 返回 401，并且不在用户操作活跃期内 清除token信息并跳转到登录页面
                    ToLogin()
                }
                errInfo.message = "登录失效，请重新登录"; 
            }
            // 403 无权限
            else if (response.status == 403) {
               errInfo.message = "该操作无权限"; 
            }
            // 429 ip限流
            else if (response.status == 429) {
                errInfo.message = "刷新次数过多，请稍事休息重试！";
            }else if (response.status == 404) {
                // 404 不存在
                errInfo.message = "访问接口不存在";
           }else if (response.status == 500) {
               // 500 服务器异常
               errInfo.message = "服务器异常"; 
           }else if (response.status == 405) {
               // 405 请求http方法错误
               errInfo.message = "请求http方法错误";  
           }else if (response.status == 415) {
               // 415 不支持的请求类型
               errInfo.message = "不支持的请求类型";   
           }else {
               //其他错误参数
                errInfo.message = '请求错误' + response.status;    
           }
        }else{
            errInfo.message = "服务器断开";  
        }
		ElMessage.error(errInfo.message);
		return Promise.reject(error);
	}
);


export const refreshToken = (params: any) => {
    return axios.get(`/api/Login/RefreshToken`, {params: params}).then(res => res.data);
};

function ToLogin(){
    
    Session.clear(); // 清除浏览器全部临时缓存
    router.push('/login')
}

// 导出 axios 实例
export default service;
